/**
 ***************************************************************************************************
 *
 * @file app_tys.c
 *
 * @brief ty server application entry point
 *
 * Copyright (C) Eker 2021
 *
 ***************************************************************************************************
 */

/**
 ***************************************************************************************************
 * @addtogroup APP
 * @{
 ***************************************************************************************************
 */

/*
 * INCLUDE FILES
 ***************************************************************************************************
 */
#include "app.h"
#include "ty_ble.h"

#define APP_LOG_DOMAIN      "tys"
#define APP_LOG_LEVEL       APP_LOG_LEVEL_TYS
#include "app_log.h"

#define BLE_TYS_FIFO_BUF_SIZE             1024
/*
 * GLOBAL VARIABLE DEFINITIONS
 ***************************************************************************************************
 */
// Application Module Environment Structure
struct app_ty_server_env_tag app_ty_server_env;

uint8_t app_ty_trans_data_buffer[BLE_TYS_FIFO_BUF_SIZE];

/*
 * GLOBAL FUNCTION DEFINITIONS
 ***************************************************************************************************
 */
void app_ty_server_init(void)
{
    // Reset the environment
    memset(&app_ty_server_env, 0, sizeof(struct app_ty_server_env_tag));
}

void app_ty_server_add_service(void)
{
    struct ty_server_db_cfg* db_cfg;
    
    // Allocate the CREATE_DB_REQ
    struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD,
                                                             TASK_GAPM, TASK_APP,
                                                             gapm_profile_task_add_cmd,
                                                             sizeof(struct ty_server_db_cfg));
    // Fill message
    req->operation   = GAPM_PROFILE_TASK_ADD;
    req->sec_lvl     = PERM(SVC_AUTH, NO_AUTH)|PERM(SVC_MI,ENABLE);
    req->prf_task_id = TASK_ID_TYS;
    req->app_task    = TASK_APP;
    req->start_hdl   = 0;

    // Set parameters and add some parameter if needed
    db_cfg = (struct ty_server_db_cfg* ) req->param;
    db_cfg->fifo_size = BLE_TYS_FIFO_BUF_SIZE;
    db_cfg->fifo_buffer = app_ty_trans_data_buffer;
    db_cfg->connect_num = BLE_APP_TYS_CONNECT_MAX; // max connect num
    db_cfg->svc_type = 1; // 128 bit uuid

    // Send the message
    ke_msg_send(req);
}

void app_ty_server_enable_prf(uint8_t conidx)
{
    // Allocate the message
    struct ty_server_enable_req * req = KE_MSG_ALLOC(TY_SERVER_ENABLE_REQ,
                                                     KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TYS), conidx),
                                                     KE_BUILD_ID(TASK_APP,conidx),
                                                     ty_server_enable_req);

    // Fill in the parameter structure
    req->conidx = conidx;

    // Send the message
    ke_msg_send(req);
}

void app_ty_server_disable_prf(uint8_t conidx)
{
    uint8_t is_find=0;

    app_ty_server_env.ntf_en[conidx] = 0;
    for(uint8_t i=0; i<BLE_APP_TYS_CONNECT_MAX; i++)
    {
        if (app_ty_server_env.ntf_en[i])
        {
            is_find++;
        }
    }
    if (is_find == 0)
    {
    }
}

void app_ty_server_send_data(uint8_t conidx, uint8_t* pdata, uint16_t len)
{
    // Allocate the message
    struct ty_server_send_ntf_cmd * cmd = KE_MSG_ALLOC_DYN(TY_SERVER_SEND_NTF_CMD,
                                                           KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TYS), conidx),
                                                           KE_BUILD_ID(TASK_APP, conidx),
                                                           ty_server_send_ntf_cmd,
                                                           len);
    cmd->conidx = conidx;
    cmd->length = len;
    memcpy(cmd->value, pdata, len);

    // Send the message
    ke_msg_send(cmd);
}

/*
 * LOCAL FUNCTION DEFINITIONS
 ***************************************************************************************************
 */
static int ty_server_enable_rsp_handler(ke_msg_id_t const msgid,
                                        struct ty_server_enable_rsp const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    LOG_DBG("Enable server.");
    return (KE_MSG_CONSUMED);
}

static int ty_server_ntf_cfg_ind_handler(ke_msg_id_t const msgid,
                                         struct ty_server_ntf_cfg_ind const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id)
{
    uint8_t conidx = KE_IDX_GET(src_id);
    uint8_t is_find=0;
    for(uint8_t i=0;i<BLE_APP_TYS_CONNECT_MAX;i++)
    {
        if (app_ty_server_env.ntf_en[i])
        {
            is_find++;
        }
    }

    if(param->ntf_cfg == PRF_CLI_START_NTF || param->ntf_cfg == PRF_CLI_START_IND)
    {
        LOG_DBG("Notify enable.");
        app_ty_server_env.ntf_en[conidx] = 1;
    }
    else if(param->ntf_cfg == PRF_CLI_STOP_NTFIND)
    {
        LOG_DBG("Notify disable.");
        app_ty_server_env.ntf_en[conidx] = 0;
    }
    return (KE_MSG_CONSUMED);
}

static int ty_server_send_empty_handler(ke_msg_id_t const msgid,
                                        struct ty_server_buffer_empty_evt const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    LOG_DBG("Fifo empty!");
    return (KE_MSG_CONSUMED);
}

static int ty_server_send_full_handler(ke_msg_id_t const msgid,
                                       struct ty_server_buffer_empty_evt const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    LOG_WRN("Fifo full!");
    return (KE_MSG_CONSUMED);
}

static int ty_server_error_handler(ke_msg_id_t const msgid,
                                   struct ty_server_error_evt const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    LOG_ERR("Send error!!");
    return (KE_MSG_CONSUMED);
}

static int ty_server_write_ind_handler(ke_msg_id_t const msgid,
                                       struct ty_server_write_ind const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    LOG_DBG_ARRAY_EX("RECV", param->value, param->length);

    // tuya
    ty_ble_receive_data_handler(param->value, param->length);

    return (KE_MSG_CONSUMED);
}

/**
 ****************************************************************************************
 * @brief KE_MSG_DEFAULT_HANDLER message handler
 *
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int app_ty_server_msg_dflt_handler(ke_msg_id_t const msgid,
                                          void const *param,
                                          ke_task_id_t const dest_id,
                                          ke_task_id_t const src_id)
{
    // Drop the message
    return (KE_MSG_CONSUMED);
}

/*
 * LOCAL VARIABLE DEFINITIONS
 ****************************************************************************************
 */
// Default State handlers definition
const struct ke_msg_handler app_ty_server_msg_handler_list[] =
{
    // Note: first message is latest message checked by kernel so default is put on top.
    {KE_MSG_DEFAULT_HANDLER,        (ke_msg_func_t)app_ty_server_msg_dflt_handler},
    {TY_SERVER_ENABLE_REQ,          (ke_msg_func_t)ty_server_enable_rsp_handler},
    {TY_SERVER_NTF_CFG_IND,         (ke_msg_func_t)ty_server_ntf_cfg_ind_handler},
    {TY_SERVER_BUFFER_EMPTY,        (ke_msg_func_t)ty_server_send_empty_handler},
    {TY_SERVER_BUFFER_FULL,         (ke_msg_func_t)ty_server_send_full_handler},
    {TY_SERVER_ERROR,               (ke_msg_func_t)ty_server_error_handler},
    {TY_SERVER_WRITE_IND,           (ke_msg_func_t)ty_server_write_ind_handler},
};

const struct app_subtask_handlers app_ty_server_handlers = APP_HANDLERS2(app_ty_server);

/// @} APP
